﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Intorise.Common;
using System.Threading;
using System.Threading.Tasks;
using Intorise.API;
using System.IO;
using System.Drawing.Imaging;

namespace Bot
{
    public partial class MainWindow : Form
    {
        protected ValidateCodeHelper helper = null;

        protected TimeSpan timeout = new TimeSpan(0, 1, 0);
        protected bool running = false;
        protected bool quit = false;
        protected bool loginInputCompleted = false;
        protected bool loginCompleted = false;
        protected bool gameEnterd = false;
        protected bool playCompleted = false;
        protected bool isAutoFight = false;
        protected bool isNewPlayer = false;//是否新建角色
        protected int CurrentLevel = 0;

        protected static string completedAccountFile = AppDomain.CurrentDomain.BaseDirectory + "已完成.txt";
        protected static string ImageRoot = AppDomain.CurrentDomain.BaseDirectory + "Images\\";
        protected IntPtr FlashHandle = IntPtr.Zero;
        protected IntPtr IEHandle = IntPtr.Zero;
        protected static string loginUrl = "http://web.4399.com/user/?_a=login";
        protected static string enterGameUrl = "http://web.4399.com/stat/togame.php?target=rxlz2&server_id=S{0}&cid=3000&time=1467460839598";
        protected Bitmap currentImage = null;

        #region 窗口关闭标识
        protected bool isClosed每日充值 = false;

        #endregion
        #region 图片
        protected static Bitmap Img_稍后再说 = null;
        protected static Bitmap Img_接受任务 = null;
        protected static Bitmap Img_完成任务 = null;
        protected static Bitmap Img_立即使用 = null;
        protected static Bitmap Img_断线 = null;
        protected static Bitmap Img_已登录 = null;
        protected static Bitmap Img_签到并领奖 = null;
        protected static Bitmap Img_再领一次 = null;
        protected static Bitmap Img_建角色 = null;
        protected static Bitmap Img_关闭 = null;
        protected static Bitmap Img_每日充值 = null;

        List<LevelItem> LevelItems = new List<LevelItem>();

        #endregion

        protected List<Account> accounts = new List<Account>();
        protected List<Account> completedAccounts = new List<Account>();
        protected Account currentAccount = null;

        public MainWindow()
        {
            InitializeComponent();
            Form.CheckForIllegalCrossThreadCalls = false;
            this.Load += Form1_Load;
        }

        protected virtual void Initialize()
        {
            try
            {
                InitializeCommon();
            }
            catch (Exception ex)
            {
                ConsoleBLL.WriteLineError("初始化一般数据时出错：");
                ConsoleBLL.WriteLineError(ex.Message + "\r\n" + ex.StackTrace);
            }

            try
            {
                InitializeImages();
            }
            catch (Exception ex)
            {
                ConsoleBLL.WriteLineError("初始化图像数据时出错：");
                ConsoleBLL.WriteLineError(ex.Message + "\r\n" + ex.StackTrace);
            }

            try
            {
                LoadAccount();
            }
            catch (Exception ex)
            {
                ConsoleBLL.WriteLineError("加载账号时出错：");
                ConsoleBLL.WriteLineError(ex.Message + "\r\n" + ex.StackTrace);
            }

            currentAccount = accounts.FirstOrDefault();
            if (currentAccount != null)
            {
                BeginCloseAlertWindow();
                running = true;
                BeginLogin();
            }
        }

        /// <summary>
        /// 游戏挂机主线程
        /// </summary>
        protected virtual void Play()
        {
            ConsoleBLL.WriteLineInfo(currentAccount + "开始执行挂机脚本...");

            //Goto(457, 423);
            //Thread.Sleep(100000);

            //Sign();//签到

            //AutoFight();
            RunScript();
            //Run_BOSS之家小怪挂机脚本();

            ConsoleBLL.WriteLineInfo("挂机主线程已结束");
            if (!playCompleted)
            {
                ConsoleBLL.WriteLineInfo("任务未完成，重新开始...");
                BeginLogin();
            }
            else
            {
                ConsoleBLL.WriteLineInfo(currentAccount + "任务已完成");
                try
                {
                    using (var writer = File.AppendText(completedAccountFile))
                    {
                        writer.WriteLine(currentAccount.ServerID + "," + currentAccount.Username + "," + currentAccount.Password);
                    }
                }
                catch (Exception ex)
                {
                    ConsoleBLL.WriteLineError(currentAccount + "写入已完成文件时出错");
                    ConsoleBLL.WriteLineError(ex.Message);
                }

                accounts.Remove(currentAccount);
                currentAccount = accounts.FirstOrDefault();
                if (currentAccount != null)
                {
                    BeginLogin();
                }
                else
                {
                    running = false;
                    ConsoleBLL.WriteLineInfo("所有账号已完成");
                }
            }
        }

        /// <summary>
        /// 挂机脚本
        /// </summary>
        protected virtual void RunScript()
        {

        }



        #region 登录相关
        protected virtual void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            ConsoleBLL.WriteLine(e.Url.ToString());
            if (e.Url.ToString() == loginUrl)
            {
                this.wb.DocumentCompleted -= wb_DocumentCompleted;
                ConsoleBLL.WriteLineInfo("登录页面已打开，开始登录线程...");
                Task.Factory.StartNew(() => { Login(); });
                return;
            }
            if (loginInputCompleted && !loginCompleted && e.Url.ToString() == "http://web.4399.com/")
            {
                this.wb.DocumentCompleted -= wb_DocumentCompleted;
                ConsoleBLL.WriteLineInfo("登录成功..."); loginCompleted = true;
            }
        }

        protected virtual void processLoginResult()
        {
            ConsoleBLL.WriteLineInfo("开始检测登录结果...");
            HtmlElement status = GetUserInfo();
            DateTime begin = DateTime.Now;

            while (!quit && !loginCompleted)
            {
                if ((DateTime.Now - begin) > timeout && !loginCompleted)
                {
                    ConsoleBLL.WriteLineError("检测登录结果超时（" + timeout + "），退出..."); break;
                }
                Thread.Sleep(500);
            }
            if (!loginCompleted)
            {
                ConsoleBLL.WriteLineError("登录失败...");
                BeginLogin();
            }
            else
            {
                ConsoleBLL.WriteLineInfo("登录成功...开始进入游戏...");
                this.wb.Stop();
                this.wb.Navigate(string.Format(enterGameUrl, currentAccount.ServerID));
                Task.Factory.StartNew(ProcessEnterGame);
            }
        }

        protected virtual void ProcessEnterGame()
        {
            ConsoleBLL.WriteLineInfo("开始检测进入游戏结果...");
            Thread.Sleep(5000);
            Task.Factory.StartNew(HideTop);

            FlashHandle = this.wb.Handle;
            DateTime begin = DateTime.Now;
            StringBuilder sb = new StringBuilder();

            while (true)
            {
                if (IsTimeout(begin))
                {
                    ConsoleBLL.WriteLineError("进入游戏超时（" + timeout + "），退出...");
                    FlashHandle = IntPtr.Zero;
                    break;
                }
                var h = Windows.FindWindowEx(FlashHandle, IntPtr.Zero, null, null);
                //ConsoleBLL.WriteLine("Window handle:" + h);

                if (h != IntPtr.Zero)
                {
                    FlashHandle = h;
                    Windows.GetClassName(h, sb, 1024);
                    //ConsoleBLL.WriteLine("Window class name:" + sb.ToString());
                    if (sb.ToString() == "MacromediaFlashPlayerActiveX")
                    {
                        break;
                    }
                }
                Thread.Sleep(2000);
            }

            ConsoleBLL.WriteLineInfo("Flash 句柄：" + FlashHandle);

            if (FlashHandle != IntPtr.Zero)
            {
                ConsoleBLL.WriteLineInfo("已找到Flash窗口...等待游戏加载成功...");

                begin = DateTime.Now;
                while (true)
                {
                    Thread.Sleep(2000);
                    if (IsTimeout(begin))
                    {
                        ConsoleBLL.WriteLineError("进入游戏超时（" + timeout + "），重新开始...");
                        BeginLogin();
                        break;
                    }
                    CaptureCurrentImage();

                    var point = ImageTools.SearchImage(currentImage, Img_建角色, new Rectangle(704, 494, 42, 22));
                    if (point != Point.Empty)
                    {
                        isNewPlayer = true;
                        ConsoleBLL.WriteLineInfo("建立角色...");
                        FlashLeftClick(684, 502);
                        FlashLeftClick(684, 502);
                        FlashLeftClick(684, 502);
                        FlashLeftClick(929, 323);
                        FlashLeftClick(929, 323);
                        FlashLeftClick(542, 572);
                        Thread.Sleep(3000);

                        continue;
                    }

                    if (isNewPlayer)
                    {
                        FlashLeftClick(996, 666);//跳过动画
                    }

                    point = ImageTools.SearchImage(currentImage, Img_已登录, new Rectangle(862, 686, 28, 22));

                    if (point != Point.Empty)
                    {
                        ConsoleBLL.WriteLineInfo("已进入游戏...");
                        gameEnterd = true;
                        GetLevelFromImg();

                        bool shzs = false;
                        bool gxgg = false;
                        bool mrcz = false;

                        for (var i = 0; i < 3; i++)
                        {
                            CaptureCurrentImage();
                            if (!gxgg)
                            {
                                gxgg = Process更新公告();
                            }

                            if (!shzs)
                            {
                                shzs = Process稍后再说();
                            }

                            if (!mrcz)
                            {
                                mrcz = Process每日充值();
                            }
                            if (shzs && gxgg && mrcz) { break; }
                            Thread.Sleep(3000);
                        }

                        Task.Factory.StartNew(Play);//开始挂机主线程
                        break;
                    }

                    ConsoleBLL.WriteLineInfo("等待进入游戏...");
                    Thread.Sleep(10000);
                }
            }
        }



        //断线检测
        protected virtual bool CheckDisconnect()
        {
            var point = ImageTools.SearchImage(currentImage, Img_断线, new Rectangle(425, 346, 255, 36));
            return point != Point.Empty;
        }

        protected virtual void BeginLogin()
        {
            this.wb.Navigate("about:blank");
            this.quit = false;
            this.gameEnterd = false;
            this.loginInputCompleted = false;
            this.loginCompleted = false;
            this.wb.Stop();
            this.wb.DocumentCompleted += wb_DocumentCompleted;
            this.wb.Navigate(loginUrl);
        }

        protected virtual void Login()
        {
            ConsoleBLL.WriteLine(currentAccount + "开始登录...");
            HtmlElement username = null;
            HtmlElement pwd = null;
            HtmlElement loginBtn = null;
            DateTime begin = DateTime.Now;

            while (!quit && !loginInputCompleted)
            {
                if (IsTimeout(begin))
                {
                    ConsoleBLL.WriteLineError("登录输入超时（" + timeout + "），退出..."); break;
                }
                username = GetHtmlElement("s_user");
                if (username == null)
                {
                    ConsoleBLL.WriteLineWaring("没找到用户名输入控件...稍后再次尝试...");
                    Thread.Sleep(500); continue;
                }
                pwd = GetHtmlElement("s_password");
                if (pwd == null)
                {
                    ConsoleBLL.WriteLineWaring("没找到密码输入控件...稍后再次尝试...");
                    Thread.Sleep(500); continue;
                }
                loginBtn = GetLoginButton();
                if (loginBtn == null)
                {
                    ConsoleBLL.WriteLineWaring("没找到登录按钮控件...稍后再次尝试...");
                    Thread.Sleep(500); continue;
                }

                this.Invoke(new Action(() =>
                {
                    this.wb.DocumentCompleted += wb_DocumentCompleted;
                    loginInputCompleted = true;
                    ConsoleBLL.WriteLineInfo("用户名密码已输入，开始登录...");
                    username.SetAttribute("value", currentAccount.Username);
                    pwd.SetAttribute("value", currentAccount.Password);
                    username.SetAttribute("value", currentAccount.Username);
                    pwd.SetAttribute("value", currentAccount.Password);
                    loginBtn.InvokeMember("click");

                    Task.Factory.StartNew(() => { processLoginResult(); });
                }));
                Thread.Sleep(5000);
            }
        }
        #endregion

        #region 一次任务
        /// <summary>
        /// 签到
        /// </summary>
        protected virtual void Sign()
        {
            FlashKeyPress(Keys.Escape);
            FlashLeftClick(738, 60, 2000);
            FlashLeftClick(230, 153, 2000);

            CaptureCurrentImage();
            var point = ImageTools.SearchImage(currentImage, Img_签到并领奖, new Rectangle(712, 419, 175, 45));
            if (point != Point.Empty)
            {
                FlashLeftClick(762, 433);
                ConsoleBLL.WriteLineInfo("签到并领取奖励");
            }
            else
            {
                point = ImageTools.SearchImage(currentImage, Img_再领一次, new Rectangle(712, 419, 175, 45));
                if (point != Point.Empty)
                {
                    //Helper.MouseLeftClickP(FlashHandle, 762, 433);
                    ConsoleBLL.WriteLineInfo("签到奖励已领取");
                }
            }

            CaptureCurrentImage();
            Process立即使用();

            FlashLeftClick(805, 568);
            ConsoleBLL.WriteLineInfo("领取累计签到奖励");
            CaptureCurrentImage();
            Process立即使用();

            FlashLeftClick(332, 149);
            FlashLeftClick(595, 589);
            ConsoleBLL.WriteLineInfo("领取七日礼包");
            CaptureCurrentImage();
            Process立即使用();

            FlashLeftClick(424, 151);
            FlashLeftClick(830, 261);
            FlashLeftClick(830, 341);
            FlashLeftClick(830, 421);
            FlashLeftClick(830, 501);
            FlashLeftClick(830, 581);
            ConsoleBLL.WriteLineInfo("领取在线奖励");
            CaptureCurrentImage();
            Process立即使用();

            FlashLeftClick(260, 280);
            Thread.Sleep(200);
            for (var i = 0; i < 5; i++)
            {
                FlashLeftClick(830, 261, 500);
                FlashLeftClick(830, 341, 500);
                FlashLeftClick(830, 421, 500);
                FlashLeftClick(830, 501, 500);
                FlashLeftClick(830, 581, 500);
                FlashLeftClick(904, 610, 1000);
                FlashLeftClick(904, 610, 1000);
                CaptureCurrentImage();
                Process立即使用();
            }
            ConsoleBLL.WriteLineInfo("领取等级礼包");

            FlashLeftClick(260, 350);
            FlashLeftClick(631, 569);
            CaptureCurrentImage();
            Process立即使用();
            ConsoleBLL.WriteLineInfo("领取每周在线");

            FlashLeftClick(519, 151);
            FlashLeftClick(829, 429);
            CaptureCurrentImage();
            Process立即使用();
            ConsoleBLL.WriteLineInfo("领取离线经验");

            FlashKeyPress(Keys.Escape);
            FlashKeyPress(Keys.Escape);
            FlashKeyPress(Keys.Escape);
            FlashKeyPress(Keys.Escape);
            FlashKeyPress(Keys.Escape);
        }
        #endregion

        #region 按钮处理

        protected virtual bool Process每日充值()
        {
            var point = ImageTools.SearchImage(currentImage, Img_每日充值, new Rectangle(534, 163, 112, 25), 0.9);
            if (point != Point.Empty)
            {
                isClosed每日充值 = true;
                Helper.MouseLeftClickP(FlashHandle, 911, 198);
                ConsoleBLL.WriteLineInfo("关闭每日充值");
                return true;
            }
            return false;
        }

        protected virtual bool Process更新公告()
        {
            var point = ImageTools.SearchImage(currentImage, Img_关闭, new Rectangle(815, 126, 49, 40), 0.9);
            if (point != Point.Empty)
            {
                Helper.MouseLeftClickP(FlashHandle, point.X + 5, point.Y + 5);
                ConsoleBLL.WriteLineInfo("关闭更新公告");
                return true;
            }
            return false;
        }

        protected virtual bool Process稍后再说()
        {
            //var point = ImageTools.SearchImage(currentImage, Img_稍后再说, new Rectangle(591, 546, 120, 42));
            var point = ImageTools.SearchImage(currentImage, Img_稍后再说, new Rectangle(530, 336, 527, 294), 0.9);
            if (point != Point.Empty)
            {
                Helper.MouseLeftClickP(FlashHandle, point.X + 5, point.Y + 5);
                ConsoleBLL.WriteLineInfo("点击稍后再说");
                return true;
            }
            return false;
        }

        protected virtual void Process接受任务()
        {
            //var point = ImageTools.SearchImage(currentImage, Img_接受任务, new Rectangle(558, 484, 113, 40));
            var point = ImageTools.SearchImage(currentImage, Img_接受任务, new Rectangle(315, 336, 527, 294), 0.9);
            if (point != Point.Empty)
            {
                Helper.MouseLeftClickP(FlashHandle, point.X + 5, point.Y + 5);
                ConsoleBLL.WriteLineInfo("点击接受任务");
            }
        }

        protected virtual void Process完成任务()
        {
            //530,336,527,294
            //var point = ImageTools.SearchImage(currentImage, Img_完成任务, new Rectangle(558, 484, 113, 40));
            var point = ImageTools.SearchImage(currentImage, Img_完成任务, new Rectangle(315, 336, 527, 294), 0.9);
            if (point != Point.Empty)
            {
                Helper.MouseLeftClickP(FlashHandle, point.X + 5, point.Y + 5);
                ConsoleBLL.WriteLineInfo("点击完成任务");
            }
        }

        protected virtual void Process立即使用()
        {
            //var point = ImageTools.SearchImage(currentImage, Img_立即使用, new Rectangle(867, 548, 225, 100));
            var point = ImageTools.SearchImage(currentImage, Img_立即使用, new Rectangle(530, 336, 527, 294), 0.9);
            if (point != Point.Empty)
            {
                Helper.MouseLeftClickP(FlashHandle, point.X + 5, point.Y + 5);
                ConsoleBLL.WriteLineInfo("点击立即使用");
            }
        }
        #endregion

        #region 游戏操作
        /// <summary>
        /// 分解装备
        /// </summary>
        protected virtual void Fenjie()
        {
            ConsoleBLL.WriteLine("开始分解装备.");
            FlashLeftClick(384, 652, 1000);
            FlashLeftClick(419, 160, 1000);
            FlashLeftClick(340, 592, 1000);
            FlashLeftClick(469, 592, 1000);
            FlashKeyPress(Keys.Escape);
            FlashKeyPress(Keys.Escape);
        }

        /// <summary>
        /// 开始挂机
        /// </summary>
        protected virtual void AutoFight()
        {
            isAutoFight = !isAutoFight;
            Helper.MouseLeftClickP(FlashHandle, 745, 658);
        }

        /// <summary>
        /// 移动到给定图片上的坐标(打开地图后的坐标)
        /// </summary>
        /// <param name="point"></param>
        protected virtual void Goto(Point point)
        {
            Goto(point.X, point.Y);
        }

        /// <summary>
        /// 移动到给定图片上的坐标(打开地图后的坐标)
        /// </summary>
        /// <param name="point"></param>
        protected virtual void Goto(int x, int y)
        {
            FlashKeyPress(Keys.M);
            FlashLeftClick(x, y);
            FlashKeyPress(Keys.M);
        }

        #endregion

        #region 公共方法
        /// <summary>
        /// 初始化一般数据
        /// </summary>
        protected virtual void InitializeCommon()
        {
            helper = new ValidateCodeHelper(AppDomain.CurrentDomain.BaseDirectory + "37code.cds", "zheshijie101");
            completedAccountFile = AppDomain.CurrentDomain.BaseDirectory + "已完成.txt";
            ImageRoot = AppDomain.CurrentDomain.BaseDirectory + "Images\\";
        }

        /// <summary>
        /// 初始化图像数据
        /// </summary>
        protected virtual void InitializeImages()
        {
            ImageTools.PixelColorRedundance = 30;

            LevelItem item = null;
            for (var i = 1; i < 100; i++)
            {
                if (File.Exists(ImageRoot + "\\level\\" + i + ".bmp"))
                {
                    item = new LevelItem { Level = i };
                    item.ItemImage = (Bitmap)Image.FromFile(ImageRoot + "\\level\\" + i + ".bmp");
                    LevelItems.Add(item);
                }
            }

            Img_稍后再说 = (Bitmap)Image.FromFile(ImageRoot + "稍后再说.bmp");
            Img_接受任务 = (Bitmap)Image.FromFile(ImageRoot + "接受任务.bmp");
            Img_完成任务 = (Bitmap)Image.FromFile(ImageRoot + "完成任务.bmp");
            Img_立即使用 = (Bitmap)Image.FromFile(ImageRoot + "立即使用.bmp");
            Img_断线 = (Bitmap)Image.FromFile(ImageRoot + "断线.bmp");
            Img_已登录 = (Bitmap)Image.FromFile(ImageRoot + "登录.bmp");
            Img_签到并领奖 = (Bitmap)Image.FromFile(ImageRoot + "签到并领奖.bmp");
            Img_再领一次 = (Bitmap)Image.FromFile(ImageRoot + "再领一次.bmp");
            Img_建角色 = (Bitmap)Image.FromFile(ImageRoot + "建角色.bmp");
            Img_关闭 = (Bitmap)Image.FromFile(ImageRoot + "关闭.bmp");
            Img_每日充值 = (Bitmap)Image.FromFile(ImageRoot + "每日充值.bmp");
        }

        /// <summary>
        /// 加载账号
        /// </summary>
        protected virtual void LoadAccount()
        {
            accounts.Clear();
            completedAccounts.Clear();
            var lines = File.ReadAllLines(AppDomain.CurrentDomain.BaseDirectory + "账号.txt");
            if (!File.Exists(completedAccountFile))
            {
                using (var writer = File.CreateText(completedAccountFile))
                {
                    writer.Write("");
                }
            }
            var completed = File.ReadAllLines(completedAccountFile);

            foreach (var line in completed)
            {
                var items = line.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
                if (items.Length == 3)
                {
                    completedAccounts.Add(new Account { Username = items[1], Password = items[2], ServerID = items[0] });
                }
            }

            foreach (var line in lines)
            {
                var items = line.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
                if (items.Length == 3 && completedAccounts.Count(c => c.Username == items[1] && c.ServerID == items[0]) == 0)
                {
                    accounts.Add(new Account { Username = items[1], Password = items[2], ServerID = items[0] });
                }
            }
        }

        protected virtual void Hide界面()
        {
            ConsoleBLL.WriteLine("隐藏一些界面.");
            FlashLeftClick(648, 218);
            FlashLeftClick(890, 50);
            FlashLeftClick(10, 595);
            FlashLeftClick(101, 227);
            FlashKeyPress(Keys.Escape);
            FlashKeyPress(Keys.Escape);
        }

        /// <summary>
        /// 获取验证码
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        protected virtual string GetCode(Bitmap image)
        {
            MemoryStream stream = new MemoryStream();
            image.Save(stream, ImageFormat.Bmp);
            var data = stream.ToArray();
            stream.Close();
            return helper.GetVcode(data);
        }

        protected virtual void BeginCloseAlertWindow()
        {
            Thread thread = new Thread(new ParameterizedThreadStart(x =>
            {
                while (running)
                {
                    var pointer = Windows.FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, "安全警报");
                    if (pointer != IntPtr.Zero)
                    {
                        Windows.BringWindowToTop(this.wb.Handle);
                        Intorise.API.Helper.SendKeyPress(pointer, Keys.Enter);
                        ConsoleBLL.WriteLine("关闭安全警报");
                        SendKeys.SendWait("\r");
                    }
                    pointer = Windows.FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, "脚本错误");
                    if (pointer != IntPtr.Zero)
                    {
                        Windows.BringWindowToTop(this.wb.Handle);
                        Helper.MouseLeftClick(0, 0);
                        Intorise.API.Helper.SendKey(pointer, Keys.Y);
                        ConsoleBLL.WriteLine("关闭脚本错误");
                        SendKeys.SendWait("Y");
                    }
                    Thread.Sleep(1000);
                }
            }));
            thread.Start();
        }

        protected virtual void HideTop()
        {
            bool hideTop = false;
            while (!hideTop)
            {
                this.Invoke(new Action(() =>
                {
                    var middle = this.wb.Document.GetElementById("middle");
                    if (middle != null)
                    {
                        middle.Style = "top:0px;height:737px;";
                        middle.Id = "middle_changed";
                        ConsoleBLL.WriteLine("隐藏顶部");
                        hideTop = true;
                    }
                }));
                Thread.Sleep(1000);
            }
        }

        protected virtual bool IsTimeout(DateTime begin)
        {
            return (DateTime.Now - begin) > timeout;
        }

        protected virtual string GetDocumentText()
        {
            return (string)this.Invoke(new Func<string>(() =>
            {
                return wb.DocumentText;
            }));
        }

        protected virtual HtmlElement GetHtmlElement(string id)
        {
            return (HtmlElement)this.Invoke(new Func<HtmlElement>(() =>
            {
                return wb.Document.GetElementById(id);
            }));
        }

        protected virtual HtmlElement GetLoginButton()
        {
            return (HtmlElement)this.Invoke(new Func<HtmlElement>(() =>
            {
                var inputs = wb.Document.GetElementsByTagName("input");
                for (var i = 0; i < inputs.Count; i++)
                {
                    if (inputs[i].GetAttribute("type") == "submit")
                    {
                        return inputs[i];
                    }
                }
                return null;
            }));
        }

        protected virtual HtmlElement GetUserInfo()
        {
            HtmlElement element = null;
            ManualResetEvent reset = new ManualResetEvent(false);
            this.Invoke(new Action(() =>
            {
                var divs = wb.Document.GetElementsByTagName("div");
                for (var i = 0; i < divs.Count; i++)
                {
                    if (divs[i].OuterHtml.Contains("my_info my_info_box"))
                    {
                        element = divs[i]; break;
                    }
                }
                reset.Set();
            }));
            reset.WaitOne();
            return element;
        }

        /// <summary>
        /// 抓取当前Flash图像
        /// </summary>
        protected virtual void CaptureCurrentImage()
        {
            if (currentImage != null)
            {
                currentImage.Dispose();
            }
            currentImage = Helper.CaptureWindow(FlashHandle);
        }

        /// <summary>
        /// 在flash指定坐标单机鼠标左键并延迟指定毫秒数(默认500)
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="sleep"></param>
        protected virtual void FlashLeftClick(int x, int y, int sleep = 500)
        {
            Helper.MouseLeftClickP(FlashHandle, x, y);
            Thread.Sleep(sleep);
        }

        /// <summary>
        /// 向flash发送按键并延迟指定毫秒数(默认500)
        /// </summary>
        /// <param name="sleep"></param>
        protected virtual void FlashKeyPress(Keys key, int sleep = 500)
        {
            Helper.SendKeyPress(FlashHandle, key);
            Thread.Sleep(sleep);
        }

        /// <summary>
        /// 获取角色等级
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        protected virtual void GetLevel()
        {
            var levelImage = currentImage.Clone(new RectangleF(124, 88, 21, 16), currentImage.PixelFormat);
            var text = GetCode(levelImage);
            int level = 0;
            if (int.TryParse(text, out level))
            {
                CurrentLevel = level;
            }
        }

        /// <summary>
        /// 获取角色等级
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        protected virtual void GetLevelFromImg()
        {
            var levelImage = currentImage.Clone(new RectangleF(124, 88, 21, 16), currentImage.PixelFormat);
            var list = LevelItems.Where(w => w.Level > CurrentLevel).OrderBy(w => w.Level).ToList();

            foreach (LevelItem item in list)
            {
                var point = ImageTools.SearchImage(currentImage, item.ItemImage, new Rectangle(121, 85, 34, 24));
                if (point != Point.Empty)
                {
                    CurrentLevel = item.Level; break;
                }
            }
        }

        protected virtual void GetLevelFromOCR()
        {
            var image = ImageTools.Clone(currentImage, 125, 90, 19, 12);
            ImageTools.ReplaceColor(image, Color.White, Color.Black, Color.White);
            var levelText = BotHelper.OcrScan(image);
            int level = 0;
            if (int.TryParse(levelText, out level))
            {
                CurrentLevel = level;
            }
        }



        #endregion

        #region 事件处理

        private void Form1_Load(object sender, EventArgs e)
        {
            if (this.DesignMode) { return; }
            if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "../../../Documents/images"))
            {
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "../../../Documents/images");
            }
            ConsoleBLL.AddDatetime = true;
            ConsoleBLL.Enabled = true;
            ConsoleBLL.TextBox = this.msg;
            Initialize();
        }

        //抓图
        protected virtual void button1_Click(object sender, EventArgs e)
        {
            var bitmap = Helper.CaptureWindow(this.wb.Handle);
            bitmap.Save(AppDomain.CurrentDomain.BaseDirectory + "../../../Documents/images/" + DateTime.Now.ToString("yyyyMMdd HHmmssms") + ".bmp", ImageFormat.Bmp);
            bitmap.Dispose();
        }

        //停止主线程执行
        protected virtual void button2_Click(object sender, EventArgs e)
        {
            quit = true;
        }

        protected virtual void button3_Click(object sender, EventArgs e)
        {
            Helper.SendKeyPress(FlashHandle, Keys.M);
        }
        #endregion
    }
}
